<?php

namespace App\Service\OpenShop\Feishu;


use App\Enums\OpenShop\InvestmentPromotion\MainProcessEnum;
use App\Enums\OpenShop\InvestmentPromotion\UploadFileResourceEnum;
use App\Enums\OpenShop\MissionTemplateEnum;
use App\Enums\WorkOrder\OrderEnum;
use App\Events\OpenShop\OpenShopProcessEvent;
use App\Events\OpenShop\SignSiteMissionEvent;
use App\Http\Resources\OpenShop\ShopEngineeringConstruction\ShopEngineeringConstructionResource;
use App\Http\Validate\OpenShop\ShopEngineeringConstruction\ShopEngineeringConstructionValidate;
use App\Models\Cruise\CruiseOrderModel;
use App\Models\Cruise\CruiseOrderProcessModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopMainProcessModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderLogModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopUploadFileResourceModel;
use App\Models\OpenShop\ShopCheckAccept\OpenShopCheckAcceptModel;
use App\Models\OpenShop\ShopEngineeringConstruction\OpenShopEngineeringConstructionModel;
use App\Models\OpenShop\StartBusiness\OpenShopStartBusinessModel;
use App\Remote\Rms\RmsShopRemote;
use App\Remote\Rms\RmsUserRemote;
use App\Service\BaseService;
use App\Service\Common\SmsService;
use App\Service\Cruise\CruiseTemplate\CruiseTemplateService;
use App\Service\Cruise\Mission\CruiseOrderInputService;
use App\Service\OpenShop\Message\SendFsService;
use App\Service\System\SystemNotifyService;
use App\Service\WorkOrder\FunctionOpen\FunctionOpenService;
use App\Support\ChangeSupport;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;

/**
 * @author Green Leaf <786407418@qq.com>
 */
class ShopEngineeringConstructionService extends BaseService
{

    /**
     * 营建施工开始
     *
     * @param object $rmsUser
     * @param object $params
     * @throws Exception
     */
    public static function engineeringConstructionStart(object $rmsUser, object $params)
    {
        try {
            //todo 营建开始时间写入 & step变更
            OpenShopEngineeringConstructionModel::query()
                                                ->where("orderNo", $params->orderNo)
                                                ->update(array_merge([
                                                    "updatedAt"    => time(),
                                                    "updatedByUid" => $rmsUser->id,
                                                    "step"         => MainProcessEnum::ENGINEER_CONSTRUCT_START,
                                                ], (array)$params));


            //todo  任务
            event(new SignSiteMissionEvent(
                $params->orderNo,
                MissionTemplateEnum::STEP_STATUS_9,
                $rmsUser->id
            ));

            //todo 流程日志写入
            event(new OpenShopProcessEvent(
                $rmsUser->id,
                OpenShopMainProcessModel::query()->where("orderNo", $params->orderNo)->first()->id,
                MainProcessEnum::MAIN_PROCESS_ENGINEER_CONSTRUCT,
                MainProcessEnum::ENGINEER_CONSTRUCT_START
            ));
        } catch (Exception $exception) {
            handleException($exception);
        }
    }

    /**
     * @param object $rmsUser
     * @param object $params
     * @param object $attachParams
     * @throws Exception|GuzzleException
     */
    public static function engineeringConstructionFinish(object $rmsUser, object $params, object $attachParams)
    {
        try {
            DB::beginTransaction();
            $shopEngineeringConstruction = OpenShopEngineeringConstructionModel::query()
                                                                               ->with('mainProcessRel')
                                                                               ->where("orderNo", $params->orderNo)
                                                                               ->first();

            //todo 营建确认 & 数据写入
            OpenShopEngineeringConstructionModel::query()
                                                ->where("orderNo", $params->orderNo)
                                                ->update(array_merge([
                                                    "updatedAt"    => time(),
                                                    "updatedByUid" => $rmsUser->id,
                                                    "step"         => MainProcessEnum::ENGINEER_CONSTRUCT_CONFIRM_FINISH,
                                                ], (array)$params));

            //todo 附件入库
            OpenShopUploadFileResourceModel::query()->insert((array)$attachParams);

            //todo 营建流程转入验收流程
            OpenShopCheckAcceptModel::query()
                                    ->updateOrCreate([
                                        'orderNo' => $shopEngineeringConstruction->orderNo
                                    ], [
                                        "mainProcessId" => $shopEngineeringConstruction->mainProcessId,
                                        "step"          => MainProcessEnum::SHOP_CHECK_ASSIGN_MANAGER_STAY,
                                        "createdAt"     => time(),
                                        "createdByUid"  => $rmsUser->id
                                    ]);

            $missionList = OpenShopMainProcessModel::where('orderNo', $shopEngineeringConstruction->orderNo)
                                                   ->first()->stepStatusLists;
            $missionList = json_decode($missionList, true);

            $isNeed     = false;
            $updateData = [];
            if (in_array(MissionTemplateEnum::STEP_STATUS_11, $missionList)) {
                $step       = MainProcessEnum::MAIN_PROCESS_SHOP_CHECK;
                $updateData = [
                    'nowStepStatus' => 11
                ];

            } else {
                $step   = MainProcessEnum::MAIN_PROCESS_START_BUSINESS;
                $isNeed = true;

            }


            $data = [
                "updatedAt"    => time(),
                "updatedByUid" => $rmsUser->id,
                "step"         => $step,
            ];

            //todo 主流程更新
            OpenShopMainProcessModel::query()
                                    ->where("orderNo", $params->orderNo)
                                    ->update(array_merge($data, $updateData));

            DB::commit();

            //Todo 开店流程进入到工程营建，筹备部确认施工完成后自动切换为正常
            RmsShopRemote::switchShopOn(
                OpenShopMainProcessModel::query()->where("orderNo", $params->orderNo)->first()->shopId
            );


            //todo 流程日志写入
            event(new OpenShopProcessEvent(
                $rmsUser->id,
                $shopEngineeringConstruction->mainProcessId,
                MainProcessEnum::MAIN_PROCESS_ENGINEER_CONSTRUCT,
                MainProcessEnum::ENGINEER_CONSTRUCT_CONFIRM_FINISH
            ));

            if ($isNeed) {
                // 关闭所有的event queue
                Config::set('event.connection', 'sync');
            }

            //TODO 任务
            event(new SignSiteMissionEvent(
                $params->orderNo,
                MissionTemplateEnum::STEP_STATUS_10,
                $rmsUser->id
            ));

            if ($isNeed) {
                //选址信息插入
                OpenShopStartBusinessModel::query()->insert([
                    'orderNo'       => $shopEngineeringConstruction->orderNo,
                    'mainProcessId' => $shopEngineeringConstruction->mainProcessId,
                    'createdAt'     => time()
                ]);

                $templateId       = CruiseTemplateService::getTemplateId(CruiseOrderModel::TYPE_NEW_SHOP_HELP);
                $cruiseOrderModel = (new CruiseOrderModel)->initShopHelper($shopEngineeringConstruction->orderNo,
                    $shopEngineeringConstruction->mainProcessRel->shopId, $templateId);
                CruiseOrderProcessModel::initCruiseOrderProcess($cruiseOrderModel->id);
                (new CruiseOrderInputService($cruiseOrderModel))->initOrderInput($templateId);

                CruiseOrderInputService::helpSendFs($shopEngineeringConstruction->orderNo,
                    CruiseOrderModel::STATUS_NOT_SUBMIT);
            }


        } catch (Exception $exception) {
            DB::rollBack();
            handleException($exception);
        }

        // 新增几个通知
        $shopId = $shopEngineeringConstruction->mainProcessRel->shopId;

        // 判断 夸父收银 是否开通
        $kfCash = RmsShopRemote::functionOpenDetail($shopId)['functionOpenDetail'][4]['isOpen'] ?? false;
        if (!FunctionOpenService::checkWorkOrderExist(
                $shopId, OrderEnum::PROBLEM_PID_5,
                OrderEnum::PROBLEM_PID_5_CHILDREN_105
            ) && !$kfCash) {
            (new SendFsService($params->orderNo))->choubeiSend();
            (new SendFsService($params->orderNo))->notifyChoubeiSend();

            // 短信通知
            (new SmsService())->aliyunSend($shopEngineeringConstruction->baseInfoRel->mobile,
                config('sms.template.workOrderOpenShouYinjiNotify'), []);
            // 门店提送提醒
            $pushUidMap = array_values(
                array_column(
                    (RmsUserRemote::getShopManagerUserByShopId([$shopId])['lists'] ?? []),
                    "userId"
                )
            );
            SystemNotifyService::customerBatchPush(
                $pushUidMap,
                '开通夸父收银功能提醒',
                "尊敬的夸父伙伴您好，夸父提醒您：收银系统需要申请收款账号，请点击查看详情，提交资料，申请功能开通。",
                config('webUrl.notify_web_cdn_url') . '#/pages/work-order/function-activation/form/index?type=105',
                $shopId
            );
        }

        // 筹备确认施工完成更新门店属性(迁址状态更改为否)
        RmsShopRemote::updateShopAttribute($shopId, ['relocationStatus' => 2]);
    }

    /**
     * @param string $orderNo
     * @return array|void
     * @throws Exception
     */
    public static function detail(string $orderNo)
    {
        try {
            $shopEngineeringConstruction = OpenShopEngineeringConstructionModel::query()
                                                                               ->with([
                                                                                   "attachRel" => function ($query) {
                                                                                       $query->whereIn("position",
                                                                                           array_keys(UploadFileResourceEnum::ENGINEERING_CONSTRUCTION_MAP))
                                                                                             ->where("isDeleted", 0);
                                                                                   }
                                                                               ])
                                                                               ->where("orderNo", $orderNo)
                                                                               ->get();

            return [
                "detail" => ShopEngineeringConstructionResource::collection($shopEngineeringConstruction)
                                                               ->getIterator()->current()
            ];
        } catch (Exception $exception) {
            handleException($exception);
        }
    }

    /**
     * 营建编辑
     *
     * @param object $rmsUser
     * @param object $params
     * @param object $attachParams
     * @throws Exception
     */
    public static function update(object $rmsUser, object $params, object $attachParams)
    {
        try {
            DB::beginTransaction();

            //todo 营建确认 & 数据写入
            ChangeSupport::getInstance()->singleUpdate(
                new OpenShopEngineeringConstructionModel(),
                function ($query) use ($params) {
                    $query->where("orderNo", $params->orderNo);
                },
                array_merge(["updatedAt" => time(), "updatedByUid" => $rmsUser->id], (array)$params),
                "营建基础数据变更",
                [
                    "engineeringConstructionStartTime"  => [
                        "type" => ChangeSupport::FILED_TYPE_DATE_YMD,
                        "desc" => "开始时间"
                    ],
                    "finishStatus"                      => [
                        "type" => ChangeSupport::FILED_TYPE_ENUM,
                        "desc" => "完成状态",
                        "enum" => OpenShopEngineeringConstructionModel::FINISH_STATUS_MAP
                    ],
                    "engineeringConstructionFinishTime" => [
                        "type" => ChangeSupport::FILED_TYPE_DATE_YMD,
                        "desc" => "结束时间"
                    ],
                ]
            );

            //todo 附件入库
            ChangeSupport::getInstance()->attachBatchUpdate(
                new OpenShopUploadFileResourceModel(),
                function ($query) use ($params) {
                    $query->where("orderNo", $params->orderNo)
                          ->whereIn("position", array_keys(UploadFileResourceEnum::ENGINEERING_CONSTRUCTION_MAP))
                          ->where("isDeleted", 0);
                },
                (array)$attachParams,
                "附件变更",
                OpenShopUploadFileResourceModel::$orderLogTranslate
            );

            //todo 写入订单日志
            ChangeSupport::getInstance()->batchChangesWriteToOrderLog(
                OpenShopSignOrderModel::getOrderIdByOrderNo($params->orderNo),
                OpenShopSignOrderLogModel::UPDATE_ENGINEERING_CONSTRUCTION,
                $rmsUser->username,
                $rmsUser->id,
            );

            DB::commit();
        } catch (Exception $exception) {
            DB::rollBack();
            handleException($exception);
        }
    }

}
